﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using SocialPlatformSDK.Hammock.Authentication.OAuth;
using SocialPlatformSDK.Hammock.Web;
using System.Text;
using System.Linq;
using SocialPlatformSDK.Services.Util;
using SocialPlatformSDK.Hammock;
using SocialPlatformSDK.Model;
using SocialPlatformSDK.Hammock.Silverlight.Compat;

namespace SocialPlatformSDK.Services
{


    /// <summary>
    /// 所有 Service(除了 OAuthService) 的基类，用于和底层网络接口 Hammock 进行通信.
    /// </summary>
    public abstract class BaseService<T> 
        where T: ServiceArgument,new()
    {
        protected AccessToken accessToken;
        protected IOAuthConfigruation oAuthConfigruationBase;
   
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="accessToken">
        /// 指示该 Service 所需要的 AccessToken，优先级高于 OAuthConfigruation.AccessToken, 若该值为 null,
        /// SDK 将默认使用 OAuthConfigruation.AccessToken.
        /// </param>
        public BaseService(AccessToken accessToken, IOAuthConfigruation oAuthConfigruationBase)
        {
            this.accessToken = accessToken;
            this.oAuthConfigruationBase = oAuthConfigruationBase;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        public BaseService()
            : this(null,null)
        { }
        
        //private Dictionary<string, object> parseArg(ServiceArgument arg)
        //{

        //}

        /// <summary>
        /// 通过Get方法异步调用API.
        /// </summary>
        /// <param name="path">API的相对地址.</param>
        /// <param name="arg">参数列表.</param>
        /// <param name="handler">需要回调的委托.</param>
        protected void Get(string path, ServiceArgument arg , RestCallback handler)
        {
            if (null == arg)
            {
                arg = new T();
            }
            
            Get(path, arg.ParseArg(), handler);
        }
        
        private void Get(string path, Dictionary<string, object> args, RestCallback handler)
        {
            AccessToken token = (this.accessToken == null) ? oAuthConfigruationBase.AccessToken : this.accessToken;

            if (null == token)
            {
                throw new MissingAccessTokenExcception();
            }


            RestClient client = new RestClient()
            {
                Authority = oAuthConfigruationBase.APIUrl,
                HasElevatedPermissions = true,             
                Encoding = Encoding.UTF8
            };

            RestRequest request = new RestRequest()
            {
                Path = path,
                Method = WebMethod.Get,
                Encoding = Encoding.UTF8
            };
            //request.AddHeader("Authorization", string.Format("OAuth2 {0}", token.AccesssToken));
            foreach (var i in args)
            {
                request.AddParameter(i.Key, i.Value.ToString());
            }

            client.BeginRequest(request, new RestCallback(handler));
        }


        /// <summary>
        /// 用 Post 方法异步上传数据
        /// </summary>
        /// <param name="path">API的要对路径</param>
        /// <param name="arg">参数列表</param>
        /// <param name="handler">回调委托</param>
        protected void Post(string path, ServiceArgument arg, RestCallback handler)
        {
            Post(path, arg.ParseArg(), handler);
        }

        private void Post(string path, Dictionary<string, object> args, RestCallback handler)
        {
            AccessToken token = (this.accessToken == null) ? oAuthConfigruationBase.AccessToken : this.accessToken;

            if (null == token)
            {
                throw new MissingAccessTokenExcception();
            }

            var client = new RestClient
            {
                Authority = oAuthConfigruationBase.APIUrl,
                HasElevatedPermissions = true,
                Encoding = Encoding.UTF8
            };

            var request = new RestRequest
            {
                Method = WebMethod.Post,
                Path = path,
                CopyFieldToParameters = true,
                Encoding = Encoding.UTF8,
              
            };
            //request.AddHeader("Authorization", string.Format("OAuth2 {0}", token.AccesssToken));
            bool needsPost = (args.Values.FirstOrDefault(a => (a is UploadPic)) == null) ? false : true;

            foreach (var i in args)
            {
                if (i.Value is UploadPic)
                {
                    UploadPic pic = i.Value as UploadPic;
                    request.AddFile(i.Key, pic.FileName, pic.FullPathName, ((pic.Extention == ".jpg") ? "image/jpeg" : "image/png"));
                }
                else
                {
                    if (needsPost)
                    {
                        request.AddField(i.Key, i.Value.ToString());
                    }
                    else
                        request.AddParameter(i.Key, i.Value.ToString());
                }
            }

            client.BeginRequest(request, handler);
        }
    }

   
}
